/**
*  
* @Function 批次导入数据Controller 
* @ProjectName credit-data-platform 
* @PackageName com.py.credit.controller    
* @FileName BatchDataController.java    
* @Date 2018年9月27日上午11:51:06
* @Author Min DongXv
* @Copyright (c) 2018, 金电联行 All Rights Reserved.   
*   
*/
package com.py.credit.controller;

import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSONArray;
import com.py.credit.common.ServiceException;
import com.py.credit.common.logs.ExceptionLogger;
import com.py.credit.common.rest.RestServiceResult;
import com.py.credit.entity.Column;
import com.py.credit.entity.SysUser;
import com.py.credit.entity.common.OptionalColumn;
import com.py.credit.service.BatchDataService;
import com.py.credit.service.BatchLogService;
import com.py.credit.service.ColumnService;
import com.py.credit.service.DataEntryService;
import com.py.credit.service.RemoteBaseService;
import com.py.credit.service.excel.read.service.InspectDataStyleService;
import com.py.credit.utils.DateUtil;
import com.py.credit.utils.MapCache;
import com.py.framework.core.annotation.IgnoreAuthority;
import com.py.framework.core.common.Page;
import com.py.framework.core.helper.HttpServletHelper;

/**
 * 
 * @Function 批次导入数据Controller
 * @ClassName BatchDataController
 * @Date 2018年9月27日 上午11:51:06
 * @Author Min DongXv
 * 
 */
@RestController
@RequestMapping(value = "/batchData")
public class BatchDataController extends BaseController {

	private static final String BATCH_DATA = "batchData";

	@Autowired
	private BatchDataService batchDataService;

	@Autowired
	private ColumnService columnService;

	@Autowired
	private RemoteBaseService remoteBaseService;
	

	
	@Autowired
	@Qualifier("default")
	private InspectDataStyleService inspectDataStyleService;

	@Autowired
	private DataEntryService dataEntryService;

	@Autowired
	private BatchLogService batchLogService;

	@RequestMapping(value = "/getOptionalColumns.json")
	public RestServiceResult<List<OptionalColumn>> getOptionalColums(
			@RequestParam(value = "tableId", defaultValue = "", required = true) int tableId) {
		List<OptionalColumn> columns = columnService.getOptionalColumnByTableId(tableId);
		OptionalColumn c2 = new OptionalColumn("OFFICE_NAME", "采集部门", "varchar", true, "input", true, null, false);
		columns.add(c2);
		OptionalColumn c3 = new OptionalColumn("REAL_NAME", "采集人员", "varchar", true, "input", true, null, false);
		columns.add(c3);
		OptionalColumn c = new OptionalColumn("typeMsg", "数据状态", "varchar", true, "input", true, null, false);
		columns.add(c);
		OptionalColumn c4 = new OptionalColumn("creditTime", "采集日期", "timestamp", true, "input", true, null, false);
		columns.add(c4);
	
		return new RestServiceResult<>(columns);
	}

	@RequestMapping(value = "/getAdvancedConditionColumns.json")
	public RestServiceResult<List<OptionalColumn>> getAdvancedConditionColumns(
			@RequestParam(value = "tableId", defaultValue = "", required = true) int tableId) {
		List<OptionalColumn> columns = columnService.getOptionalColumnByTableId(tableId);
		OptionalColumn c2 = new OptionalColumn("OFFICE_NAME", "采集部门", "varchar", true, "input", true, null, false);
		columns.add(c2);
		OptionalColumn c3 = new OptionalColumn("REAL_NAME", "采集人员", "varchar", true, "input", true, null, false);
		columns.add(c3);
		OptionalColumn c4 = new OptionalColumn("creditTime", "采集日期", "timestamp", true, "input", true, null, false);
		columns.add(c4);
		return new RestServiceResult<>(columns);
	
	}

	@RequestMapping(value = "/addShowColunms.json")
	public RestServiceResult<String> addShowColunms(@RequestParam(value = "columns", required = true) String[] columns,
			@RequestParam(value = "tableId", required = true) String tableId, HttpServletRequest request) {
		RestServiceResult<SysUser> user = remoteBaseService.getCurrentUser(HttpServletHelper.getUserToken(request));
		if (RestServiceResult.CODE_SUCCESS == user.getCode()) {
			SysUser userInfo = user.getData();
			if (null != userInfo) {
				MapCache.set(BATCH_DATA + userInfo.getId() + "_" + tableId, columns);
			} else {
				ExceptionLogger.error("BatchDataController#addShowColunms", "未获取到当前用户信息！");
			}
		} else {
			ExceptionLogger.error("BatchDataController#addShowColunms", "未获取到当前用户信息！");
		}
		return new RestServiceResult<>();
	}

	/**
	 * 
	 * @api {get} /batchData/dataList.json 批次数据详情
	 * @apiName dataList
	 * @apiVersion 0.0.1
	 * @apiGroup 数据采集
	 * @apiParam {Integer} tableId 表ID
	 * @apiParam {String} batchId 批次ID
	 * @apiParamExample {json} 请求参数示例 {"tableId":1,"batchId":"1"}
	 * @apiSuccess {String} code 状态码:1 成功 -1 失败
	 * @apiSuccess {String} msg 错误信息
	 * @apiSuccess {int} count 结果集数据量
	 * @apiSuccess {String} data 结果集
	 * @apiSuccess {String} result 动态列,无标准数据
	 * @apiSuccessExample {json} 成功返回结果 {}
	 */
	@RequestMapping(value = "/dataList.json")
	public RestServiceResult<List<Map<String, Object>>> dataList(HttpServletRequest request,
			@RequestParam(value = "condition", defaultValue = "", required = true) String condition, Page page,
			@RequestParam(value = "tableId", defaultValue = "", required = true) Integer tableId,
			@RequestParam(value = "batchId", defaultValue = "", required = true) String batchId) {
		RestServiceResult<List<Map<String, Object>>> result = new RestServiceResult<>();
		RestServiceResult<SysUser> user = remoteBaseService.getCurrentUser(HttpServletHelper.getUserToken(request));
		String[] configColumns = null;
		 String rolename="";
		 Long deptId=null;
		 Long userID=null;
		if (RestServiceResult.CODE_SUCCESS == user.getCode()) {
			SysUser userInfo = user.getData();
	
			if (null != userInfo) {
				
				//获取当前用户所属部门
				deptId=	userInfo.getOfficeId();
				//获取当前用户ID
				userID = userInfo.getId();
				//获取用户角色信息
				rolename = userInfo.getRoleName();
				configColumns = (String[]) MapCache.get(BATCH_DATA + userInfo.getId() + "_" + tableId);
				String configColumn = StringUtils.join(configColumns, ",");
				configColumn = StringUtils.replace(configColumn, ",typeMsg", "");
				configColumns = StringUtils.split(configColumn, ",");
			} else {
				ExceptionLogger.error("BatchDataController#dataList", "未获取到当前用户信息！");
			}
			// 获取批次
//			BatchLog batchLog = batchLogService.selectPermissionLimit(batchId, userInfo);
//			if (null == batchLog || StringUtils.isBlank(batchLog.getId())) {
//				return result;
//			}
		} else {
			ExceptionLogger.error("BatchDataController#dataList", "未获取到当前用户信息！");
		}
		
		List<String> showColumns = (configColumns == null || configColumns.length == 0)
				? columnService.getColumnENByTableId(tableId) : Arrays.asList(configColumns);
		try {
			//系统管理员看到所有采集数据
			if(rolename.equals("系统管理员")) {
				List<Map<String, Object>> data = batchDataService.batchDataByConditionForPage(showColumns,
						new String[] { "record_id"}, condition, page, tableId, batchId,null,null);	
						result.setCount(page.getTotalCount());
						result.setData(data);
			}else if(rolename.equals("部门管理员")){//部门管理员看到本部门所有采集数据
				List<Map<String, Object>> data = batchDataService.batchDataByConditionForPage(showColumns,
						new String[] { "record_id"}, condition, page, tableId, batchId,deptId,null);	
						result.setCount(page.getTotalCount());
						result.setData(data);
			}else {//普通用户看到本部门自己所有采集数据
				List<Map<String, Object>> data = batchDataService.batchDataByConditionForPage(showColumns,
						new String[] { "record_id"}, condition, page, tableId, batchId,deptId,userID);	
						result.setCount(page.getTotalCount());
						result.setData(data);
			}
			
			return result;
		} catch (Exception e) {
			ExceptionLogger.error("BatchDataController#dataList", "查询批次数据异常！");
			result.setCode(RestServiceResult.CODE_UNKNOW);
			result.setMsg("查询批次数据异常！");
			return result;
		}
	}

	/**
	 * 
	 * @api {get} /batchData/updataData.json 数据更新
	 * @apiName updataData
	 * @apiVersion 0.0.1
	 * @apiGroup 数据采集
	 * @apiParam {Integer} tableId 表ID
	 * @apiParam {String} chackData 修改数据
	 * @apiParam {Integer} dataId 记录ID
	 * @apiParamExample {json} 请求参数示例 {"tableId":1,"dataId":1,"chackData":""}
	 * @apiSuccess {String} code 状态码:1 成功 -1 失败
	 * @apiSuccess {String} msg 错误信息
	 * @apiSuccess {int} count 结果集数据量
	 * @apiSuccess {String} data 结果集
	 * @apiSuccess {String} result
	 * @apiSuccessExample {json} 成功返回结果 {}
	 */
	@RequestMapping(value = "/updataData.json")
	public RestServiceResult<Object> updataData(HttpServletRequest request,
			@RequestParam(value = "tableId", defaultValue = "", required = true) int tableId,
			@RequestParam(value = "chackData", defaultValue = "", required = true) String chackData,
			@RequestParam(value = "dataId", defaultValue = "", required = true) int dataId) {
		RestServiceResult<Object> result = new RestServiceResult<>();
		// 获取当前用户信息
		RestServiceResult<SysUser> user = remoteBaseService.getCurrentUser(HttpServletHelper.getUserToken(request));
		SysUser userInfo = null;
		if (RestServiceResult.CODE_SUCCESS == user.getCode()) {
			userInfo = user.getData();
			if (null == userInfo || userInfo.getId() <= 0) {
				result.setCode(RestServiceResult.CODE_UNKNOW);
				result.setMsg("系统异常，请稍后再试！");
				ExceptionLogger.error("BatchDataController#updataData", "未获取到当前用户信息！");
				return result;
			}
		} else {
			result.setCode(user.getCode());
			result.setMsg(user.getMsg());
			return result;
		}
		@SuppressWarnings("unchecked")
		Map<String, Object> data = JSONArray.parseObject(chackData, Map.class);
		try {
			List<Column> columns = columnService.getListByTableId(tableId);
			// 数据校验
			String sb = inspectDataStyleService.dataCheck(tableId, data, columns);
			if (StringUtils.isNotBlank(sb)) {
				result.setCode(RestServiceResult.CODE_UNKNOW);
				result.setMsg(sb);
				return result;
			}
			// 数据修改
			dataEntryService.editData(tableId, data, columns, dataId, userInfo);
			return result;
		} catch (ServiceException e) {
			ExceptionLogger.error("BatchDataController#updataData", "ERROR:" + e.getMessage(), e);
			result.setCode(RestServiceResult.CODE_UNKNOW);
			result.setMsg(e.getMessage());
			return result;
		} catch (Exception e) {
			ExceptionLogger.error("BatchDataController#updataData", "数据更新异常！ERROR:" + e.getMessage(), e);
			result.setCode(RestServiceResult.CODE_UNKNOW);
			result.setMsg("数据更新异常，请稍后再试！");
			return result;
		}
	}

	/**
	 * 
	 * @api {get} /batchData/deleteData.json 数据删除
	 * @apiName deleteData
	 * @apiVersion 0.0.1
	 * @apiGroup 数据采集
	 * @apiParam {Integer} tableId 表ID
	 * @apiParam {Integer} dataId 数据ID
	 * @apiParamExample {json} 请求参数示例 {"tableId":1,"dataId":1}
	 * @apiSuccess {String} code 状态码:1 成功 -1 失败
	 * @apiSuccess {String} msg 错误信息
	 * @apiSuccess {int} count 结果集数据量
	 * @apiSuccess {String} data 结果集
	 * @apiSuccessExample {json} 成功返回结果 {}
	 */
	@RequestMapping(value = "/deleteData.json")
	@ResponseBody
	public RestServiceResult<Object> deleteData(HttpServletRequest request,
			@RequestParam(value = "tableId", defaultValue = "", required = true) int tableId,
			@RequestParam(value = "dataIds", defaultValue = "", required = true) String dataIds) {
		RestServiceResult<Object> result = new RestServiceResult<>();
		// 获取当前用户信息
		RestServiceResult<SysUser> user = remoteBaseService.getCurrentUser(HttpServletHelper.getUserToken(request));
		SysUser userInfo = null;
		if (RestServiceResult.CODE_SUCCESS == user.getCode()) {
			userInfo = user.getData();
			if (null == userInfo || userInfo.getId() <= 0) {
				result.setCode(RestServiceResult.CODE_UNKNOW);
				result.setMsg("系统异常，请稍后再试！");
				ExceptionLogger.error("BatchDataController#updataData", "未获取到当前用户信息！");
				return result;
			}
		} else {
			result.setCode(user.getCode());
			result.setMsg(user.getMsg());
			return result;
		}
		String[] record_ids = dataIds.split(",");
		try {
			for (String id : record_ids) {
				dataEntryService.delData(tableId, Integer.valueOf(id), userInfo);
			}	
		
			return result;
		} catch (ServiceException e) {
			result.setCode(RestServiceResult.CODE_UNKNOW);
			result.setMsg(e.getMessage());
			ExceptionLogger.error("BatchDataController#deleteData", "ERROR:" + e.getMessage(), e);
			return result;
		} catch (Exception e) {
			result.setCode(RestServiceResult.CODE_UNKNOW);
			result.setMsg("数据删除异常，请稍后再试！");
			ExceptionLogger.error("BatchDataController#deleteData", "数据删除异常ERROR:" + e.getMessage(), e);
			return result;
		}
	}
	
	@RequestMapping(value = "/export.json")
	public RestServiceResult<List<Map<String, Object>>> exportData(
			@RequestParam(value = "tableId", defaultValue = "", required = true) Integer tableId,
			@RequestParam(value = "fileName", defaultValue = "", required = true) String fileName,
			@RequestParam(value = "batchId", defaultValue = "", required = true) String batchId,
			@RequestParam(value = "condition", defaultValue = "", required = true) String condition,
			@RequestParam(value = "columnEN", defaultValue = "", required = true) String columnEN, Page page,
			HttpServletResponse response, HttpServletRequest request) {
		page.setLimit(100000);
		RestServiceResult<List<Map<String, Object>>> result = new RestServiceResult<>();
		String token = HttpServletHelper.getUserToken(request);
		RestServiceResult<SysUser> user = remoteBaseService.getCurrentUser(HttpServletHelper.getUserToken(request));
		String[] configColumns = null;
		 String rolename="";
		 Long deptId=null;
		 Long userID=null;
		if (RestServiceResult.CODE_SUCCESS == user.getCode()) {
			SysUser userInfo = user.getData();
	
			if (null != userInfo) {
				
				//获取当前用户所属部门
				deptId=	userInfo.getOfficeId();
				//获取当前用户ID
				userID = userInfo.getId();
				//获取用户角色信息
				rolename = userInfo.getRoleName();
				configColumns = (String[]) MapCache.get(BATCH_DATA + userInfo.getId() + "_" + tableId);
				String configColumn = StringUtils.join(configColumns, ",");
				configColumn = StringUtils.replace(configColumn, ",typeMsg", "");
				configColumns = StringUtils.split(configColumn, ",");
			} else {
				ExceptionLogger.error("BatchDataController#dataList", "未获取到当前用户信息！");
			}
			// 获取批次
//			BatchLog batchLog = batchLogService.selectPermissionLimit(batchId, userInfo);
//			if (null == batchLog || StringUtils.isBlank(batchLog.getId())) {
//				return result;
//			}
		} else {
			ExceptionLogger.error("BatchDataController#dataList", "未获取到当前用户信息！");
		}
		
		List<String> showColumns = JSONArray.parseArray(columnEN, String.class);
		Iterator<String> it = showColumns.iterator();
		while (it.hasNext()) {
			String column = it.next();
			if ("typeMsg".equals(column) ) {
				it.remove();
			}
		}
		List<OptionalColumn> optionalColumns = columnService.getOptionalColumnByTableId(tableId);
				List<Map<String, Object>> data  = new ArrayList<Map<String, Object>>();
		try {
			//系统管理员看到所有采集数据
			if(rolename.equals("系统管理员")) {
				data = batchDataService.batchDataByConditionForPage(showColumns,
						new String[] { "record_id", "status" }, condition, page, tableId, batchId,null,null);	
						result.setCount(page.getTotalCount());
						result.setData(data);
			}else if(rolename.equals("部门管理员")){//部门管理员看到本部门所有采集数据
				data = batchDataService.batchDataByConditionForPage(showColumns,
						new String[] { "record_id", "status" }, condition, page, tableId, batchId,deptId,null);	
						result.setCount(page.getTotalCount());
						result.setData(data);
			}else {//普通用户看到本部门自己所有采集数据
				data = batchDataService.batchDataByConditionForPage(showColumns,
						new String[] { "record_id", "status" }, condition, page, tableId, batchId,deptId,userID);	
						result.setCount(page.getTotalCount());
						result.setData(data);
			}
			
				// 填充用户名称
	//			remoteBaseService.matchUserName(data, result, token, userIds, "managerId", "lastOperatorName");
				downloadExcelDetail(response, data, fileName, "数据采集详情", showColumns,
						optionalColumns);
		
		
		} catch (Exception e) {
			ExceptionLogger.error("BatchLogController#exportData", "数据采集导出异常！ERROR：" + e.getMessage(), e);
			result.setCode(RestServiceResult.CODE_UNKNOW);
			result.setMsg("数据采集导出异常！");
			return result;
		}
		return result;
	}
	
	public static void downloadExcelDetail(HttpServletResponse response, List<Map<String, Object>> data, String fileNanme,
			String sheetName, List<String> showColumns,   List<OptionalColumn> allColumns) throws Exception {
		response.setContentType("application/vnd.ms-excel");
		HSSFWorkbook workbook = null;
		OutputStream fOut = null;
		// 进行转码，使其支持中文文件名
		fileNanme = URLEncoder.encode(fileNanme, "UTF-8");
		response.setHeader("content-disposition", "attachment;filename=" + fileNanme + ".xls");
		// 产生工作簿对象
		workbook = new HSSFWorkbook();
		// 产生工作表对象
		HSSFSheet sheet = workbook.createSheet();
		workbook.setSheetName(0, sheetName);
		HSSFRow row = null;
		HSSFCell cell = null;
		List<String> strBT = new ArrayList<String>();
		for (String colEN : showColumns) {
			for (OptionalColumn col : allColumns) {
				if (colEN.equals(col.getColNameEN())) {
					strBT.add(col.getColNameCN());
					break;
				}
			}
		}

		// 创建标题行
		row = sheet.createRow(0);
		for (int i = 0; i < strBT.size(); i++) {
			cell = row.createCell(i);
			cell.setCellType(HSSFCell.CELL_TYPE_STRING);
			cell.setCellValue(strBT.get(i));
		}
		for (int i = 0; i < data.size(); i++) {
			row = sheet.createRow(i + 1);// 创建一行
			for (int j = 0; j < strBT.size(); j++) {
				cell = row.createCell(j);// 创建一列
				cell.setCellType(HSSFCell.CELL_TYPE_STRING);
				String showColEN = showColumns.get(j);
				Object object = data.get(i).get(showColEN);
				String widget = null;
				String type = null;
				Map<String, String> widgetValue = null;
				for (OptionalColumn col : allColumns) {
					if (showColEN.equals(col.getColNameEN())) {
						widget = col.getWidget();
						widgetValue = col.getWidgetValue();
						type = col.getType();
						break;
					}
				}

				try {

					if (object != null) {

						String columValue = object.toString();

						if ("select".equals(widget) && widgetValue != null) {

							columValue = widgetValue.get(columValue) != null ? widgetValue.get(columValue) : "";
						} else if ("timestamp".equals(type) && columValue.lastIndexOf(".") != -1) {

							columValue = DateUtil.getInstance().parseDateStr(columValue, "yyyy-MM-dd");
						}else if("datetime".equals(type)) {
							columValue = DateUtil.getInstance().parseDateStr(columValue, "yyyy-MM-dd");
						}
						cell.setCellValue(columValue);

					}
				} catch (Exception e) {
					ExceptionLogger.error("BatchLogController#exportData","数据导出错:" + showColEN + "====>", e);
				}
			}

		}

		fOut = response.getOutputStream();
		workbook.write(fOut);
		workbook.close();
		fOut.flush();
		fOut.close();
	}
	
	@IgnoreAuthority
	@RequestMapping(value = "/batchDataDeptTask.do")
	public RestServiceResult<Object> batchDataDeptTask() {
		RestServiceResult<Object> result = new RestServiceResult<Object>();
		try {
			Object data = batchDataService.batchDataDeptRun();
			result.setData(data);
			return result;
		} catch (Exception e) {
			ExceptionLogger.error("batchData#batchDataDeptTask", "批量更新双公示资源表部门数据定时任务异常！ERROR：" + e.getMessage(), e);
			result.setCode(RestServiceResult.CODE_UNKNOW);
			result.setMsg("批量更新双公示资源表部门数据定时任务异常！");
			return result;
		}
	}

	
	@RequestMapping(value = "/getTjlist.do")
	public RestServiceResult<Object> getTjlist(Page page) {
		RestServiceResult<Object> result = new RestServiceResult<Object>();
		try {
			List<Map<String, Object>> list = batchDataService.getlList(page, null, null, null);
			
			return new RestServiceResult<Object>(page.getTotalCount(), list);
	
		} catch (Exception e) {
			ExceptionLogger.error("BatchLogController#upLoadFileTask", "上传文件定时任务异常！ERROR：" + e.getMessage(), e);
			result.setCode(RestServiceResult.CODE_UNKNOW);
			result.setMsg("上传附件定时任务异常！");
			return result;
		}
	}

}
